

#include "tokenize.h"
#include <string.h>
#include <stdlib.h>


#define TOKST_NONE		0
#define TOKST_STRING1	1
#define TOKST_STRING2	2

const char *SYMBOLS = "+-*/=<>,.{}[]|!@#$%^&()~`;:\\\"\'";


int tokenize(char *line, int *argc_out, char ***argv_out)
{
	int i;
	int tokstate;
	int argc;
	int argc_max;
	char **argv;
	char sbuff[512];
	int cslen;
	int usechar;
	int push_str;

	argv = malloc(sizeof(void*) * 10);

	if (argv == NULL)
	{
		return -1;
	}
	
	argc_max = 10;
	argc = 0;
	cslen = 0;
	argc = 0;

	for(i=0; i<strlen(line); i++)
	{
		char c = line[i];
		usechar = 1;
		push_str = 0;

		if (c == '\'' && tokstate != TOKST_STRING2)
		{
			if (tokstate == TOKST_STRING1)
			{
				push_str = 1;
			}
			else if (tokstate == TOKST_NONE)
			{
				push_str = 1;
				usechar = 2;
				tokstate = TOKST_STRING1;
			}
			else
			{
				usechar = 1;
			}
		}

		if (c == '\"' && tokstate != TOKST_STRING1)
		{
			if (tokstate == TOKST_STRING2)
			{
				push_str = 1;
			}
			else if (tokstate == TOKST_NONE)
			{
				push_str = 1;
				usechar = 2;
				tokstate = TOKST_STRING2;
			}
			else
			{
				usechar = 1;
			}
		}

		if (c == ';' && tokstate == TOKST_NONE)
		{
			push_str = 2;
			usechar = 2;
		}
		
		if (c == ' ' || c == '\t' && tokstate == TOKST_NONE)
		{
			push_str = 1;
			usechar = 0;
		}

		if (usechar == 1 || usechar == 3)
		{
			sbuff[cslen++] = c;
		}

	pushback_string:
		if (push_str && cslen > 0)
		{
			argv[argc] = malloc(cslen);
			strncpy(argv[argc], sbuff, cslen);
			strcpy(sbuff, "");
			cslen = 0;
			argc++;
			if (argc >= argc_max)
			{
				argc_max += 5;
				argv = realloc(argv, sizeof(void*)*argc_max);
			}
		}

		if (usechar == 2 || usechar == 3)
		{
			sbuff[cslen] = c;
			cslen++;
		}

		if (push_str == 2)
		{
			usechar = 0;
			push_str = 1;
			goto pushback_string;
		}
	}
	
	if (cslen > 0)
	{
		argv[argc] = malloc(cslen);
		strncpy(argv[argc], sbuff, cslen);
		argc++;
	}

	*argc_out = argc;
	*argv_out = argv;
	return 0;
}


